package com.dyh.quickdemo.demos.beanReplace;

import groovy.lang.GroovyClassLoader;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/*
@Author=Joey Wheeler
@Date=2021/1/7 13:19
*/
@Component
public class BeanReplaceBiz implements ApplicationContextAware {

    private ApplicationContext ac;
    private static final GroovyClassLoader groovyClassLoader = new GroovyClassLoader();

    @Autowired
    private DefaultListableBeanFactory defaultListableBeanFactory;

    @Override
    public void setApplicationContext(ApplicationContext ac) throws BeansException {
        this.ac = ac;
    }

//    public void replace(ReplaceContext replaceContext) throws IllegalAccessException, InstantiationException {
//        Class<?> clazz = groovyClassLoader.parseClass(replaceContext.codeSrc);
//        Object newBean = clazz.newInstance();
//        String beanName = replaceContext.beanName;
//        Object oldBean = this.ac.getBean(beanName);
//        AutowireCapableBeanFactory autowireCapableBeanFactory = this.ac.getAutowireCapableBeanFactory();
//        defaultListableBeanFactory.removeBeanDefinition(beanName);
//
//        defaultListableBeanFactory.registerBeanDefinition(beanName, BeanDefinitionBuilder.genericBeanDefinition(clazz).getBeanDefinition());
//        //这里要手动注入新类里面的依赖关系
//        autowireCapableBeanFactory.autowireBean(newBean);
//    }

    public void replace(ReplaceContext replaceContext) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        Class<?> newClazz = groovyClassLoader.parseClass(replaceContext.codeSrc,"com.dyh.quickdemo.demos.beanReplace.ServiceA");
        String beanName = replaceContext.beanName;
        Object oldBean = this.ac.getBean(beanName);
        Object newBean =  newClazz.newInstance();
        AutowireCapableBeanFactory autowireCapableBeanFactory = this.ac.getAutowireCapableBeanFactory();
        defaultListableBeanFactory.removeBeanDefinition(beanName);

        defaultListableBeanFactory.registerBeanDefinition(beanName, BeanDefinitionBuilder.genericBeanDefinition(newClazz).getBeanDefinition());
        //这里要手动注入新类里面的依赖关系
        autowireCapableBeanFactory.autowireBean(newBean);
    }





    @Setter@Getter
    public static   class ReplaceContext{
        String beanName;
        String codeSrc;
        String cls;
    }



}
